﻿using Aliphant.Common.Tools;
using Aliphant.Mvvm.XEvent.Ioc;
using CuteWallpaperDemo.Models;
using DataModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;

namespace CuteWallpaperDemo.Managers
{
    public class NotifyManager : Singleton<NotifyManager>
    {
        private const int MAX_ALERT_COUNT = 5;
        private IDictionary<string, Func<NotifyWindowBase>> _serviceRegistry = new Dictionary<string, Func<NotifyWindowBase>>();
        private Queue<NotifyWindowBase> _alertItems = new Queue<NotifyWindowBase>(MAX_ALERT_COUNT);

        public void Register<T>(string name) where T : NotifyWindowBase, new()
        {
            _serviceRegistry[name] = () =>
            {
                return new T();
            };
        }

        public void Notify(string name, NotifyType type, string message)
        {
            if (!_serviceRegistry.ContainsKey(name))
            {
                return;
            }

            var window = _serviceRegistry[name].Invoke();
            window.Owner = Application.Current.MainWindow;
            window.CurrentTop = SetNotifyTop();
            window.Init(type, message);
            window.Show();

            if (_alertItems.Count == MAX_ALERT_COUNT)
            {
                var win = RemoveAlert();
                win?.Close();
            }
            _alertItems.Enqueue(window);
        }

        public NotifyWindowBase? RemoveAlert()
        {
            NotifyWindowBase? window = null;
            if (!_alertItems.TryDequeue(out window))
            {
                return null;
            }

            foreach (var item in _alertItems)
            {
                var newTop = item.Top - 10 - window.ActualHeight;
                item.MoveUpWindow(item.Top, newTop);
            }

            return window;
        }

        private double SetNotifyTop()
        {
            double top = 0d;
            foreach (var item in _alertItems)
            {
                top += item.ActualHeight + 10;
            }
            top += Application.Current.MainWindow.Top;
            return top;
        }
    }

}
